#pragma once

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>

const std::string Sep = "\r\n";     //我们自行定义的分隔符

//Encode的作用即是为序列化后的字符串添加报头，这即是我们约定的“协议”
// 例如： {json} -> len\r\n{json}\r\n, 
bool Encode(std::string &message)   
{   
    //正文部分倘若为0则直接退出
    if(message.size() == 0) return false;
    //对正文进行包装，添加报头，形成“协议”
    //我们定义的协议是：len\r\n{json}\r\n，其中len为json串长度对应的字符串类型
    std::string package = std::to_string(message.size()) + Sep + message + Sep;
    message = package;  //message作为输出型参数，将打包好的数据包送出去
    return true;
}

//Decode -- 解包，即拆分数据包的报头和正文，并进行解析
//TCP在传输过程中，不是面向数据报，而是面向字节流的，因此，传输过来的数据情况是多样的：
//例如：
// len\r\n{json}\r\n
// 123\r\n{json}\r\n -> {json}
// 123\r\n
// 123\r\n{json
// 123\r\n{json}\r
// 123\r\n{json}\r\n123\r\n{json}\r\n123\r\n{js
//因此，我们所提供解包的方法一定要全面。
bool Decode(std::string &package, std::string *content)
{
    // std::cout << "进入Decode的逻辑："<<std::endl;
    // std::cout << "package："<< package <<std::endl;

    auto pos = package.find(Sep);   //查找分隔符
    if(pos == std::string::npos)    return false;   //无分隔符，不完整，退出   
    //找到一个分隔符的情况下：
    std::string content_length_str = package.substr(0, pos);    //获取len(string)
    int content_length = std::stoi(content_length_str);         //转换len ->(int)，即正文部分的长度
    //计算一个正常的完整包的长度
    int full_length = content_length_str.size() + content_length + 2* Sep.size();

    if(package.size() < full_length)    //传递的包长度小于完整包长度，则直接退出
        return false;

    //至至此，数据包长度至少是一个完整包长度
    *content = package.substr(pos + Sep.size(), content_length);    //获取第一个完整包的正文部分
    
    //此方法只处理一个数据包，且这个数据包至少是完整的，获取其第一个完整数据包的正文部分并带出
    package.erase(0, full_length);  //消除已经处理的数据包，为后续再处理做准备
    
    return true;
}

class Request
{
public:
    Request(): _x(0), _y(0), _oper(0)
    {
    }

    Request(int x, int y, char oper) : _x(x), _y(y), _oper(oper)
    {
    }
    // 序列化
    bool Serialize(std::string &out_string)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        // 利用json库中的方法对Json库的对象进行序列化
        // 并将其转换为string
        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root, &ss);
        out_string = ss.str();
        return true;
    }
    // 反序列化
    bool Deserialize(std::string &in_string)
    {
        Json::Value root;
        Json::Reader reader;
        // 将序列化后的字节流解析转换为Json库的Value对象
        bool parsingSuccessful = reader.parse(in_string, root);
        if (!parsingSuccessful)
        {
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }

        // 将Json库中的Value对象解析转换为原本的数据
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();

        return true;
    }
    void Print()
    {
        std::cout << "oper : " <<_oper << std::endl;
        std::cout << "x : " <<_x << std::endl;
        std::cout << "y : " <<_y << std::endl;
    }
    int X() const { return _x; }
    int Y() const { return _y; }
    char Oper() const { return _oper; }

private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response() : _result(0), _code(0)
    {
    }
    Response(int result, int code) : _result(result), _code(code)
    {
    }
    // 序列化
    bool Serialize(std::string &out_string)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        // 利用json库中的方法对Json库的对象进行序列化
        // 并将其转换为string
        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root, &ss);
        out_string = ss.str();
        return true;
    }
    // 反序列化
    bool Deserialize(std::string &in_string)
    {
        Json::Value root;
        Json::Reader reader;
        // 将序列化后的字节流解析转换为Json库的Value对象
        bool parsingSuccessful = reader.parse(in_string, root);
        if (!parsingSuccessful)
        {
            std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }

        // 将Json库中的Value对象解析转换为原本的数据
        _result = root["result"].asInt();
        _code = root["code"].asInt();
    }

    int Result() const { return _result; }
    int Code() const { return _code; }
    void SetResult(int res) { _result = res; }
    void SetCode(int c) { _code = c; }

private:
    int _result; // 结果
    int _code;   // 错误码
};
